# -*- coding: utf-8 -*-
#   基础的QWidget面板
# @Time    ： 2025/11/12  15:15
# @Auther  ： 徐良
# File     :  baseQWidget.py


# -*- coding: utf-8 -*-
#   mesQWidget基本类
# @Time    ： 2023/2/2  21:41
# @Auther  ： 徐良
# File     :  baseQWidget.py
from typing import Optional, Union, Dict, Literal, Tuple
from PySide6.QtCore import Qt, QTimer
from PySide6.QtGui import QGuiApplication
from PySide6.QtWidgets import QStackedWidget, QWidget, QSplitter, QSpacerItem, QSizePolicy
import share.globalvar as gol
from aboutPanel import AboutPanel
from baseClass.tools.dialogUtils import DialogUtils, StandardButton
import logging


class BaseQWidget(QWidget):

    def __init__(self, parent=None):
        super().__init__()
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        self.setupUi(self)
        self.setWindowModality(Qt.WindowModality.ApplicationModal)  # 设置为模态

        self.toolbarFlag = 'browse'
        self.stackedW = "No"

        self.switch_to_page('pageBrowse')

    def switch_to_page(self, page_name: str) -> bool:
        """
        安全切换到指定的 stackedWidget 页面

        Args:
            page_name: 要切换的页面属性名称（字符串）

        Returns:
            bool: 是否成功切换页面

        Raises:
            不会主动抛出异常，所有错误都会捕获并返回False
        """
        # 检查 stackedWidget 是否存在
        stacked_widget: Optional[QStackedWidget] = getattr(self, 'stackedWidget', None)
        if not isinstance(stacked_widget, QStackedWidget):
            # logging.info(f"[ERROR] stackedWidget not found or invalid in {self.__class__.__name__}")
            return False

        # 获取目标页面对象
        target_page: Optional[QWidget] = getattr(self, page_name, None)
        if not isinstance(target_page, QWidget):
            self.logger.info(f"[ERROR] Page '{page_name}' not found or invalid in {self.__class__.__name__}")
            return False

        # 检查页面是否在 stackedWidget 中
        pages: list[QWidget] = [stacked_widget.widget(i) for i in range(stacked_widget.count())]
        if target_page not in pages:
            # self.logger.info(f"[ERROR] Page '{page_name}' is not a member of stackedWidget")
            return False

        # 执行页面切换
        stacked_widget.setCurrentWidget(target_page)
        return True

    def get_stackedWidget_page(self) -> Optional[str]:
        """
        获取当前编辑界面的页面名称
        :return:
        """
        stacked_widget: Optional[QStackedWidget] = getattr(self, 'stackedWidget', None)
        if not isinstance(stacked_widget, QStackedWidget):
            return None

        page_name = stacked_widget.currentWidget().objectName()
        return page_name

    @staticmethod
    def get_screen_info(self) -> Tuple[Tuple[int, int, int, int], Tuple[int, int, int, int]]:
        """
        获取主屏幕和可用屏幕的尺寸信息。

        返回：
            Tuple[Tuple[int, int, int, int], Tuple[int, int, int, int]]: 返回屏幕的总尺寸与可用尺寸。
            格式为：((主屏幕x, 主屏幕y, 主屏幕宽度, 主屏幕高度), (可用屏幕x, 可用屏幕y, 可用屏幕宽度, 可用屏幕高度))。

        异常：
            RuntimeError: 如果无法获取主屏幕信息，抛出异常。
        """
        primary_screen = QGuiApplication.primaryScreen()
        if primary_screen is None:
            raise RuntimeError("无法获取主屏幕信息")

        screen_geometry = primary_screen.geometry().getRect()
        available_geometry = primary_screen.availableGeometry().getRect()

        return screen_geometry, available_geometry

    # 更可靠的方式 - 使用绝对尺寸
    @staticmethod
    def set_splitter_ratio(splitter: QSplitter, ratio1: int, ratio2: int, max_retry=3):
        """
        设置分割器比例，带有重试机制
        """

        def try_set_ratio(retry_count=0):
            total_width = splitter.width()
            if total_width > 100:  # 确保有足够的宽度
                width1 = int(total_width * ratio1 / (ratio1 + ratio2))
                width2 = total_width - width1
                splitter.setSizes([width1, width2])
            elif retry_count < max_retry:
                # 重试
                QTimer.singleShot(100, lambda: try_set_ratio(retry_count + 1))
            else:
                pass

        try_set_ratio()

    # region 工具栏action命令中转
    def beforeClose(self) -> bool:
        """窗口关闭前校验"""
        save_button = self.get_button('保存')
        if save_button is None or not save_button.isEnabled():
            return True
        else:
            reply = DialogUtils.question('数据已更改，确认退出吗')
            if reply == StandardButton.Cancel:
                return False
        return True
    # endregion

    def action_do(self, mWin, action):
        """
        处理菜单按钮动作

        参数:
            mWin: 主窗口对象
            action: 触发的QAction对象
        """
        self.gloWin = mWin
        action_text = action.text()

        # 标准动作映射表
        action_handlers = {
            '关闭': lambda: mWin.close_tab() if self.beforeClose() else None,
            '增加一行': self.append_row,
            '插入一行': self.insert_row,
            '删除一行': self.del_row,
            '退回': self.go_back(),
            '关于': lambda: mWin.about_panel(),
            '帮助': lambda: DialogUtils.info('【帮助】功能正在开发'),
        }

        # 执行对应处理
        handler = action_handlers.get(action_text)
        if handler:
            handler()
        else:
            self.action_select(action)  # 自定义动作处理


    @staticmethod
    def get_button(btnName: str) -> Optional[QWidget]:
        """按名称获取按钮对象"""
        action_list = gol.get_value('actionList')
        return next((obj for obj in action_list if obj.text() == btnName), None)

    # endregion


    # region    单据的增加一行，插入一行，删除一行的中转管理
    def append_row(self):
        """在表体末尾添加新行"""
        self.handle_body_append()

    def insert_row(self):
        """在当前选中行插入新行"""
        self.handle_body_insert()

    def del_row(self):
        """删除当前选中行"""
        self.handle_body_del()

    # endregion


    def go_back(self):
        """从编辑界面返回浏览界面"""
        self.transfer_go_back()


    def showEvent(self, event):
        super().showEvent(event)
        if hasattr(self, 'splitter') and self.splitter and not getattr(self, '_splitter_ratio_done', False):
            # 水平分割：树（左）占 30%，表单（右）占 70%
            total = self.splitter.width() or 1000
            self.splitter.setSizes([int(total * 0.3), int(total * 0.7)])
            self._splitter_ratio_done = True